#ifndef TEST_CNN_EMNIST
#define TEST_CNN_EMNIST

#include <torch/data/datasets/base.h>
#include <torch/data/example.h>
#include <torch/types.h>

#include <cstddef>
#include <string>

/// The MNIST dataset.
class TORCH_API EMNIST : public torch::data::datasets::Dataset<EMNIST> {
public:
  /// The mode in which the dataset is loaded.
  enum class Mode { kTrain, kTest };

  /// Loads the EMNIST-digits dataset from the `root` path.
  ///
  /// The supplied `root` path should contain the *content* of the unzipped
  /// EMNIST-digits dataset, available from
  /// https://www.nist.gov/itl/products-and-services/emnist-dataset.
  explicit EMNIST(const std::string &root, Mode mode = Mode::kTrain);

  /// Returns the `Example` at the given `index`.
  torch::data::Example<> get(size_t index) override;

  /// Returns the size of the dataset.
  torch::optional<size_t> size() const override;

  /// Returns true if this is the training subset of EMNIST.
  // NOLINTNEXTLINE(bugprone-exception-escape)
  bool is_train() const noexcept;

  /// Returns all images stacked into a single tensor.
  const torch::Tensor &images() const;

  /// Returns all targets stacked into a single tensor.
  const torch::Tensor &targets() const;

private:
  torch::Tensor images_, targets_;
};

#endif /* TEST_CNN_EMNIST */
